#region usings

using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
using System.Drawing.Imaging;


using CStock;
using CUtil;
using CTrading;

using System.Threading;
using CGraph;

using EForms;
using System.Collections.Generic;
#endregion


namespace CapitalReSources
{
	/// <summary>
	/// Summary description for MainClass
	/// </summary>
	public partial class  MainClass : IMainClass
	{

        #region constructor, destructor, main


        public MainClass()
        {
            try
            {
                //System.Windows.Forms.MessageBox.Show("Start Program");
                this.programContext = CStock.ProgramContext.CreateProgramContext(false);
                chartWindows = new System.Collections.ArrayList();
                chartWindowsShare = new System.Collections.ArrayList();
                quoteUpdater = new QuoteUpdater(this.programContext);
                yahooIntraday = new WebYahooIntraday();


            }
            catch (Exception exc)
            {
                Debug.Assert(false, "Error starting CapitalReSources " + exc.Message);

            }


        }
        public void InitApplication()
        {
            try
            {
                this.programContext.Logfile.WriteTimeSpanLog("Initializing app");

                this.view = new View();

                this.programContext.Logfile.WriteTimeSpanLog("View created");
                this.AttachToObjectChangedEvents();
                this.AttachToConfigurationChanged();

                System.Windows.Forms.Form viewForm = this.view as System.Windows.Forms.Form;

                this.programContext.Logfile.WriteTimeLog("Start opening View...");

                viewForm.Focus();
                try
                {
                    UpdateViewWithTradeSystem();
                    this.UpdateViewCurrentPath();
                    if (viewForm != null)
                        viewForm.ShowDialog();
                }
                catch (Exception exc)
                {
                    Debug.Assert(false, "General unhandled program exception ", exc.Message);
                }
            }
            catch (Exception ex)
            {
                Debug.Assert(false, "Error in InitApp: " + ex.Message);
            }

        }

        private void AttachToObjectChangedEvents()
        {
            this.quoteUpdater.DatafeedHandlerYahoo.ObjectChanged += new ObjectChangedEvent(this.OnObjectChanged);

            if (this.programContext != null)
            {
                if (programContext.TradeEconomy != null)
                {
                    if (programContext.TradeEconomy.Portfolios != null)
                    {
                        for (int i = 0; i < programContext.TradeEconomy.Portfolios.Items.Count; i++)
                        {
                            IPortfolio port = (IPortfolio)programContext.TradeEconomy.Portfolios[i];
                            Portfolio p = port as Portfolio;

                            p.ObjectChanged += new ObjectChangedEvent(this.OnObjectChanged);
                            for (int j = 0; j < p.DataItems.Count; j++)
                            {
                                DataItem di = (DataItem)p.DataItems[j];
                                di.ObjectChanged += new ObjectChangedEvent(this.OnObjectChanged);
                            }
                        }

                    }
                }
            }

        }
        private void AttachToConfigurationChanged()
        {
            if (this.programContext != null)
            {
                IStockObjectBase c = programContext.Configuration as IStockObjectBase;
                if (c != null)
                {
                    c.ObjectChanged += new ObjectChangedEvent(this.OnConfigurationChanged);
                }
            }

        }
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            MainClass mc = new MainClass();

            MainClass.instance = mc;
            //mc.InitTradeSystem(); - moved to the list view
            mc.InitApplication();


            //Application.Run(new CapitalReSourcesMain());
        }

        #endregion

        #region Open/save

        public void SaveInExcel()
        {
            if (this.programContext.TradeEconomy != null)
            {
                string shortFileName = EForms.Dialogs.InputBox.Show("Please insert filename", "Excel Filename");
                if (shortFileName != null && shortFileName != string.Empty)
                {
                    if (!shortFileName.Contains(".xls"))
                    {
                        shortFileName += ".xls";
                    }
                    this.programContext.TradeEconomy.ExcelFileName = this.programContext.TradeEconomy.Path + "\\" + shortFileName;
                    this.programContext.WriteEconomyInExcel(this.programContext.TradeEconomy.ExcelFileName);
                }



            }
            else
            {
                MessageBox.Show("Could not write to Excel file ");
            }
        }

        #endregion

        #region Portfolio methods

        public IPortfolios Portfolios_Custom()
        {
            IPortfolios ports = new Portfolios();
            for (int i = 0; i < this.programContext.TradeEconomy.Portfolios.Items.Count; i++)
            {
                IPortfolio port = this.programContext.TradeEconomy.Portfolios[i] as IPortfolio;
                if (!port.StockTypePortfolio)
                {
                    ports.Items.Add(port);
                }
            }
            return ports;

        }
        public IPortfolios Portfolios_StockMarket()
        {
            IPortfolios ports = new Portfolios();
            for (int i = 0; i < this.programContext.TradeEconomy.Portfolios.Items.Count; i++)
            {
                IPortfolio port = this.programContext.TradeEconomy.Portfolios[i] as IPortfolio;
                if (port.StockTypePortfolio)
                {
                    ports.Items.Add(port);
                }
            }
            return ports;

        }

        public void AddAssetToCustomPortfolio(string portfName)
        {
            object node = GetSelection();
            IPortfolio portf = node as IPortfolio;


            if (portf != null)
            {
                //error message??

                //for (int i = 0; i < portf.DataItems.Count; i++)
                //{
                //    IDataItem di = portf.DataItems[i];
                //    //this.yahooIntraday.AddShareToList(di);
                //    PortfolioWebUpdate.DataItems.Add(di);
                //    portfolioWebUpdate.Serialize();

                //}

            }
            else
            {
                IDataItem di = node as IDataItem;
                IPortfolios ports = Portfolios_Custom();
                IPortfolio portToAdd = ports[portfName];
                Debug.Assert(portToAdd != null, "SW Error - in adding asset to custom portfolio");

                if (portToAdd != null)
                {
                    portToAdd.DataItems.Items.Add(di);

                    portToAdd.DataItems.Sort();
                    this.treeViewCustomPortfolios.Refresh();
                }

            }


        }
        public void GetPortfolioIntradayQuotes(IPortfolio port)
        {
            if (port.FetchIntradayQuotes)
            {
                UpdateFinancialData(port);

            }
        }

       
        public void OnConfigurationChanged(object sender, ObjectChangedEventArgs e)
        {
            string str = ((IStockObjectBase)sender).Name;
            string propName = e.PropertyName;

            if (propName == "DateMinSimulation")
            {
                this.View.StatusBar.Panels[0].Text = this.programContext.Configuration.Dates.DateMaxSimulation.ToShortDateString();
                this.propertyGrid.Refresh();
            }
            if (propName == "DateMaxUserTrade")
            {
                this.View.StatusBar.Panels[0].Text = this.programContext.Configuration.Dates.DateMaxUserTrade.ToShortDateString();
                this.propertyGrid.Refresh();
            }
            if (propName == "DateMinChartCurrent")
            {
                this.RefreshChartView();

            }
            if (propName == "DateMaxChartCurrent")
            {
                this.View.StatusBar.Panels[0].Text = this.programContext.Configuration.Dates.DateMaxChartCurrent.ToShortDateString();
            }
            if (propName == "ChartChanged")
            {
                this.RefreshChartView();
            }
            if (propName == "Intraday")
            {
                this.View.SetIntradayButton();
            }

        }

        public void OnObjectChanged(object sender, ObjectChangedEventArgs e)
        {
            string str = ((IStockObjectBase)sender).Name;


            IPortfolio port = sender as IPortfolio;
            IDataItem di = sender as IDataItem;
            if (port != null)
            {
                if (HandlePortfolioChanged(port, e))
                {
                    return;


                }
            }
            if (di != null)
            {
                if (HandleDataItemChanged(di, e))
                {
                    return;


                }
            }
            if (sender.GetType() == typeof(WebYahoo))
            {
                HandleDataFeedHandlerChanged(e);
                return;
            }
            if (sender.GetType() == typeof(FinancialData))
            {
                HandleFinancialDataDownloadEvent(e);
                return;
            }
            if (sender.GetType() == typeof(FundamentalData))
            {
                HandleFundamentalDataDownloadEvent(e);
                return;
            }

            //save portfolio at each change:
            //port.Serialize(this.programContext.Configuration.Directories.PortfolioPath);
            this.propertyGrid.Refresh();


        }
        public bool UpdateViewWithTradeSystem()
        {

            this.View.StatusBar.Panels[2].Text = "TradeSystem: " + this.programContext.TradeEconomy.TradeSystemName;
            return true;


        }

        public ITradeSystem DoTradeSystemBuySellSystemChange()
        {

            DialogTradeSystem tsd = new DialogTradeSystem(this.programContext);
            if (tsd.ShowDialog() == DialogResult.OK)
            {

                ChangeCurrentTradeSystem(tsd.TradeSystem);
                //UpdateViewWithTradeSystem();
                return tsd.TradeSystem;

            }
            return tsd.TradeSystem;

        }

		#endregion

        #region View 

        public void SetView(string strTabName)
        {
            SelectTabPage(strTabName);
        }
        public bool UpdateViewCurrentPath()
        {

            this.View.StatusBar.Panels[3].Text = "File location: " + this.programContext.Configuration.Directories.ApplicationPath;
            return true;

        }
        public void RefreshTree()
        {
            ITreeViewStock selectedTreeView = GetSelectedTreeView();
            selectedTreeView.FillTreeFromProgramContext();
        }
		
      
        public System.Windows.Forms.TabPage SelectTabPage(string tabPageName)
        {
            System.Windows.Forms.TabControl tc = this.tabControlStock as System.Windows.Forms.TabControl;

            System.Windows.Forms.TabPage tp;
            for (int i = 0; i < tc.TabPages.Count; i++)
            {
                tp = tc.TabPages[i];
                if (tp.Name == tabPageName)
                {
                    tc.SelectedTab = tc.TabPages[i];
                    return tp;
                }

            }
            return null;

        }
        /// <summary>
        /// 
        /// </summary>
        public void Print()
        {

            for (int i = 0; i < this.programContext.TradeEconomy.Portfolios.Items.Count; i++)
            {
                Portfolio printPortfolio = (Portfolio)this.programContext.TradeEconomy.Portfolios[i];
                System.Diagnostics.Debug.WriteLine("Portfolio: " + printPortfolio.Name);
                for (int j = 0; j < printPortfolio.DataItems.Count; j++)
                {
                    DataClass printDataClass = (DataClass)printPortfolio.DataItems[j].DataClass;
                    //string printDataClassName = printDataClass.GetParameterValue(0).ToString();
                    //System.Diagnostics.Debug.WriteLine("    " + "DataClass: " + printDataClassName);
                }
            }
        }
        #endregion

        #region chart
        public void RefreshChartView()
        {
            //ToDO
        }
        public void ChartIntradayWindow(IDataItem di)
        {
            this.View.Cursor = System.Windows.Forms.Cursors.WaitCursor;

            this.programContext.Configuration.IntradayModus = true;
            //1. see if already there

            if (ReturnIfChartWindowExists(di))
                return;

            //2. create new
            try
            {
                if (di.DataClass.QuoteCollection == null || di.DataClass.QuoteCollection.Count < 1)
                {
                    System.Windows.Forms.MessageBox.Show("No quote data for this share available - hint: try with normal (not intraday) data.  " + di.DataClass.Name);

                }
                else
                {
                    Initialize_ChartData_AndShow(di);


                }
            }

            catch (Exception exc)
            {
                System.Diagnostics.Debug.Assert(false, "Error updating chart intraday for " + di.Name, exc.Message);
            }

            this.View.Cursor = System.Windows.Forms.Cursors.Default;

        }

        public void ChartDataNotAvailable(IDataItem di)
        {
            if (this.quoteUpdater.CheckUpdateShare(di))
            {
                ChartShareWindow(di);
            }

        }

        public void RefreshIntradayChart(IDataClass dc)
        {
            try
            {


                for (int i = 0; i < chartWindows.Count; i++)
                {
                    CGraph.ChartWindow chartWindow = chartWindows[i] as CGraph.ChartWindow;
                    if (chartWindow.DataItem.DataClass.ID == dc.ID)
                    {
                        //chartWindow.ChartIntradayWindow.ProgramContext = this.programContext;

                        chartWindow.Charts[0].RefreshChart();
                        //chartWindow.Show();

                    }


                }
            }
            catch (Exception exc)
            {
                System.Diagnostics.Debug.Assert(false, "Error updating chart intraday for " + dc.Name, exc.Message);
            }


        }
        #endregion     
        
        #region Trade System

        public ITradeSystem DoTradeSystemBuySell()
        {
            ITradeSystem ts = null;
            if (this.programContext.Trader_Simulation.TradeSimulation.SetDefaultTradeSystem())
                ts = this.programContext.TradeEconomy.TradeSimulation.TradeSystem;

            return ts;


        }

        private void ShowTradeSystemDialog()
        {

        }
        public void RefreshAll()
        {
            this.View.Cursor = System.Windows.Forms.Cursors.WaitCursor;

            this.treeViewStock.FillTreeFromProgramContext();
            this.treeViewCustomPortfolios.FillTreeFromProgramContext();

            this.propertyGrid.SelectedObject = this.programContext.TradeEconomy.Portfolio_Selected;
            this.propertyGrid.Refresh();

            this.View.Cursor = System.Windows.Forms.Cursors.Default;
        }

        #endregion

        #region Fundamental Data

        public void ShowFundamentalDataInGrid()
        {
            IPortfolio port = this.programContext.TradeEconomy.Portfolio_Selected;
            TreeNode tn = GetSelectedNode();

            if (port.Name == tn.Text)
            {
                ShowPortfolioFundamentalDataInGrid();
            }
            else
            {
                ShowShareFundamentalDataInGrid();
            }


        }
        public void ShowShareFundamentalDataInGrid()
        {
            //UpdateFundamentalData(this.programContext.TradeEconomy.Portfolio_Selected.DataItem_Selected);
            IList<IFundamentalData> list = new List<IFundamentalData>();
            if (gridFundamentalData != null)
            {
                if (this.programContext.TradeEconomy.Portfolio_Selected.DataItem_Selected.FundamentalData != null &&
                    this.programContext.TradeEconomy.Portfolio_Selected.DataItem_Selected.FundamentalData.Count > 0)
                    this.gridFundamentalData.ShowFundamentalData(this.programContext.TradeEconomy.Portfolio_Selected.DataItem_Selected.FundamentalData);
                else
                {
                    this.gridFundamentalData.ShowFundamentalData(list);
                }
            }
        }
        public void ShowPortfolioFundamentalDataInGrid()
        {
            if (gridFundamentalData != null)
            {
                IPortfolio port = this.programContext.TradeEconomy.Portfolio_Selected;
                IList<IFundamentalData> list = new List<IFundamentalData>();
                for (int i = 0; i < port.DataItems.Count; i++)
                {
                    IDataItem di = port.DataItems[i];
                    if (di.FundamentalData != null && di.FundamentalData.Count > 0)
                    {
                        di.FundamentalData[0].ID = di.ID;
                        list.Add(di.FundamentalData[0] as FundamentalData);
                    }
                    else
                    {
                        list.Add(new FundamentalData(di.ID));
                    }
                }
                this.gridFundamentalData.ShowFundamentalData(list);
            }
        }

        #endregion

    }
}
